home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gnulib / libsrc98.zoo / pipe.c < prev    next >
C/C++ Source or Header  |  1993-03-01  |  6KB  |  167 lines

  1. #include <fcntl.h>
  2. #include <stat.h>
  3. #include <types.h>
  4. #include <errno.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include "lib.h"
  9. #define __MINT__
  10. #include <mintbind.h>
  11.  
  12.  
  13. extern int __mint;
  14.  
  15. #if defined(DEBUG)
  16. #  include <stdio.h>
  17. #endif
  18.  
  19. #ifndef _COMPILER_H
  20. #  include <compiler.h>
  21. #endif
  22. __EXTERN char *tmpnam __PROTO((char *buf));
  23.  
  24. /**
  25.  ** (sjk)++ These routines simulate a eunchs pipe() call using temporary 
  26.  **         files. A linked list of type *_pipe is kept as to allow as 
  27.  **         many open pipes as there are valid file descriptors. The only 
  28.  **         problem is that the pipe is initiallialy opened for writing, 
  29.  **         and all output must be done to the pipe, then call pipeclose(fd);
  30.  **         and it sets up the pipe for reading. After all input is done, 
  31.  **         call pipeclose(fd) again and this will close the pipe and delete
  32.  **         the temporary file that the pipe created.
  33.  **    
  34.  **/
  35.  
  36. struct _pipe { char p_name[40];
  37.            char flag;               /* "r"-->read, "w"-->write */
  38.            int  file_des;
  39.            struct _pipe *next;
  40.              };
  41. static struct _pipe *__pipes = NULL;
  42. static int del_list (struct _pipe *);
  43.  
  44. __EXTERN int pipeclose __PROTO((int fd));
  45. extern int (*pipeclose_p) __PROTO((int fd));
  46.  
  47. /*---------------------------------------------------------------------------*/
  48. /* Make a pipe, open the tempory file, set it up for writing, add the pipe   */
  49. /* descriptor to our linked list of pipes, and return.                       */
  50. /*---------------------------------------------------------------------------*/
  51. int pipe(fildes)
  52. int fildes[2];
  53. { int       fd; 
  54.   char name[40];
  55.   struct _pipe *p;
  56.  
  57.   tmpnam(name);                              /* Make a temporary file name. */
  58.   
  59.   /*----------------------------------------------*/
  60.   /* Open the pipe for reading and writing.       */
  61.   /*----------------------------------------------*/
  62.   fd = open(name,O_CREAT | O_TRUNC | O_RDWR | O_PIPE, 0644); 
  63.  
  64. #if defined(DEBUG)
  65.   fprintf(stderr,"opened pipe - fd : %d.\n",fd);
  66. #endif
  67.  
  68.   if (fd < 0)
  69. #if defined(DEBUG)
  70.     fprintf(stderr,"fd returns : %d! PIPE(%s) failed.\n",fd, name);
  71. #else
  72.     /* nothing */;
  73. #endif
  74.   else 
  75.     { /*------------------------------------------*/
  76.       /* Get a pipe description block and         */
  77.       /* put in the (1)file name,                 */
  78.       /*            (2)file descriptor,           */
  79.       /*            (3)file mode = "w".           */
  80.       /*------------------------------------------*/
  81.       /*-------------------------------------------------------------------*/
  82.       p = (struct _pipe *)malloc(sizeof (struct _pipe)); 
  83.       strcpy(p->p_name,name);           /* fill in name.                   */  
  84.       p->flag = 'w';                    /* initially for write.            */
  85.       p->file_des = fd;                 /* fill in the pipe descriptor.    */
  86.       if(!__pipes)
  87.     pipeclose_p = pipeclose;    /* patch in addr of close routine  */
  88.       /*-------------------------------------------------------------------*/
  89.       p->next = __pipes;                /* Link to our list of open pipes. */
  90.       __pipes     = p;
  91.       /*-------------------------------------------------------------------*/ 
  92.       fildes[0] = fildes[1] = fd;       /* we fill in fildes[].            */
  93.       if (__mint)
  94.     (void) Fcntl(fd,0L,2);          /* Make fd shared across Pexecs()  */
  95.     }
  96.   return(fd);                           /* Return the file descriptor.     */
  97. }
  98.  
  99. /*---------------------------------------------------------------------*/
  100. /* close a pipe, if the pipe was open for writing, set it to a read    */
  101. /* read pipe, and lseek to the begining of the pipe. if it was open    */
  102. /* for reading then close the pipe, delete the temporary file, and     */
  103. /* remove the pipe descriptor from the __pipes linked list.            */
  104. /*---------------------------------------------------------------------*/
  105. int
  106. pipeclose(fd)
  107. int fd;
  108. {  struct _pipe *p;
  109.    int    ifd;
  110.    for (p=__pipes; p; p=p->next)
  111.     { if (fd == p->file_des) 
  112.        { 
  113. #if defined(DEBUG)
  114.         fprintf(stderr,"Deleting pipe - mode : %c, fd : %d\n",p->flag,fd);
  115. #endif
  116.         if (p->flag == 'r') 
  117.       { int res;
  118.         ifd = __OPEN_INDEX(fd);
  119.             __open_stat[ifd].pipe = 0;            /* So close wont recurse */
  120.         res = close(fd);
  121.         unlink(p->p_name);                     /* Delete it.            */
  122.             del_list(p);                           /* delete from the list. */
  123.             return(res);                               
  124.           }
  125.         else 
  126.         if (p->flag =='w')
  127.           { p->flag = 'r';                         /* now make it read.     */
  128.             lseek(p->file_des,0,SEEK_SET);         /* read from the start.  */
  129.             return(0);
  130.           }
  131.       }
  132.     }
  133. #if defined(DEBUG)
  134.    fprintf(stderr,"attempt to close nonexistant pipe.\n");
  135. #endif
  136.    return(-1);
  137. }
  138.  
  139. /*---------------------------------------------------------------------*/
  140. /* delete a pipe descriptor from our list of pipes rooted ar __pipes.  */
  141. /*---------------------------------------------------------------------*/
  142. static int del_list(p)
  143. struct _pipe *p;
  144. { struct _pipe *q,*r;
  145.   
  146.   if (p == __pipes)                      /* Is it the first element?    */
  147.     { __pipes = p->next; 
  148.       free(p);
  149.       return(0);
  150.     }
  151.   else 
  152.     { r = __pipes->next; q = __pipes;    /* No it is interior.           */
  153.       for (; r; r = r->next)
  154.         { if (r == p)
  155.            { q->next = r->next;              /* pass over it.   */
  156.              free(r);                        /* free its space. */
  157.              return(0);                      /* go home.        */
  158.        }
  159.           q = r;                        /* update trailing pointer.    */
  160.     }
  161.     }
  162. #if defined(DEBUG)
  163.   fprintf(stderr,"Attempt to delete a nonexisting pipe form list (__pipes).");
  164. #endif
  165.   return(-1);
  166. }
  167.